package com.zzedu.web.controller.system;

import com.alibaba.fastjson.JSON;
import com.zzedu.common.constant.CacheConstants;
import com.zzedu.common.constant.Constants;
import com.zzedu.common.core.controller.BaseController;
import com.zzedu.common.core.domain.AjaxResult;
import com.zzedu.common.core.domain.LoginBody;
import com.zzedu.common.core.domain.entity.SysMenu;
import com.zzedu.common.core.domain.entity.SysUser;
import com.zzedu.common.enums.LoginType;
import com.zzedu.common.enums.PlatformLoginEnumns;
import com.zzedu.common.enums.UserTypeEnumns;
import com.zzedu.common.utils.MessageUtils;
import com.zzedu.common.utils.SecurityUtils;
import com.zzedu.common.utils.ServletUtils;
import com.zzedu.common.utils.StringUtils;
import com.zzedu.common.utils.security.LoginUser;
import com.zzedu.framework.manager.AsyncManager;
import com.zzedu.framework.manager.factory.AsyncFactory;
import com.zzedu.framework.web.domain.LoginForm;
import com.zzedu.framework.web.service.ConfigService;
import com.zzedu.framework.web.service.ISysPermissionService;
import com.zzedu.system.service.ISysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Set;

/**
 * 登录验证
 *
 * @author smarthome
 */
@RestController
public class SysLoginController extends BaseController {
    @Autowired
    ConfigService configService;
    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    ISysPermissionService permissionService;

    @Autowired
    ISysMenuService menuService;

    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping("/login")
    public AjaxResult login(@RequestBody LoginBody loginBody) {
        try {
            String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + loginBody.getUuid();
            String vc = String.valueOf(redisTemplate.opsForValue().get(verifyKey));
            String verifyCode = loginBody.getCode();
            if (vc == null) {
                throw new BadCredentialsException("验证码不存在,请先获取验证码");
            } else if (verifyCode == null || "".equals(verifyCode)) {
                throw new BadCredentialsException("请输入验证码");
            } else if (!vc.equalsIgnoreCase(verifyCode)) {
                throw new BadCredentialsException("验证码错误");
            }
            LoginForm loginForm = new LoginForm();
            loginForm.setLoginType(LoginType.PWD);
            loginForm.setVerifyCode(loginBody.getCode());
            loginForm.setPlatformLoginEnumns(PlatformLoginEnumns.PC);
            loginForm.setPassword(loginBody.getPassword());
            loginForm.setUsername(loginBody.getUsername());
            loginForm.setUserTypeEnumns(UserTypeEnumns.PLATFORM);
            UsernamePasswordAuthenticationToken token =
                    new UsernamePasswordAuthenticationToken(JSON.toJSONString(loginForm), loginBody.getPassword());
            Authentication authentication = authenticationManager.authenticate(token);
            SecurityContext securityContext = SecurityContextHolder.getContext();
            securityContext.setAuthentication(authentication);
            ServletUtils.getRequest().getSession(true).setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, securityContext);
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(SecurityUtils.getLoginName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
            return AjaxResult.success(MessageUtils.message("user.login.success"), SecurityUtils.getSessionId());
        } catch (Exception e) {
            String msg = "用户或密码错误";
            if (StringUtils.isNotEmpty(e.getMessage())) {
                msg = e.getMessage();
            }
            return error(msg);
        }
    }


    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", user);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
    }

    /**
     * 获取路由信息
     *
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public AjaxResult getRouters() {
        Long userId = SecurityUtils.getUserId();
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
        return AjaxResult.success(menuService.buildMenus(menus));
    }
}
